﻿Namespace BusinessRulesAndSupport
    ''' <summary>The Warehouse Loading Dock Scheduling Business Rule and UI Support Objects</summary>
    Public Class BusinessRuleObjects
        ''' <summary>A global reference to connect to the global wsfObjects.</summary>
        Public Shared g_wsfObjects As dbiWSF.FrameworkObjects.objWSFObjects

        ''' <summary>A global reference to connect to the global BusinessRules.</summary>
        Public g_businessRules As New BusinessRules

        ''' <summary>Creates the collection of business rules as defined in the Business Rules Functions Code below.</summary>
        ''' <param name="myWSFObjects">A reference to the Main WSF objects used in the project.</param>
        ''' <remarks>Create One Business Rule for each function in the Business Rules Functions Code below.</remarks>
        Public Sub New(ByRef myWSFObjects As dbiWSF.FrameworkObjects.objWSFObjects)
            g_wsfObjects = myWSFObjects

            'Business Rule to test for DockTypes compared to shipments.
            'Fires against shipments when added/changed.
            Dim br1 As New BusinessRule
            br1.MemberFunction = "DockTypeProximityTest"
            br1.Source = GetType(dbiWSF.FrameworkObjects.objShipment)
            g_businessRules.BusinessRuleObjects.Add(br1)

            'Business Rule to test for needed breakout docks for a shipment.
            'Fires against shipments added/changed.
            Dim br2 As New BusinessRule
            br2.MemberFunction = "BreakOutDockTest"
            br2.Source = GetType(dbiWSF.FrameworkObjects.objShipment)
            g_businessRules.BusinessRuleObjects.Add(br2)

            'Business Rule to ensure that shipments are not in conflict with each other or exceptions/recurring exceptions.
            'Fires against shipments when added/changed.
            Dim br3 As New BusinessRule
            br3.MemberFunction = "ConflictingShipmentsTest"
            br3.Source = GetType(dbiWSF.FrameworkObjects.objShipment)
            g_businessRules.BusinessRuleObjects.Add(br3)

            'Business Rule to ensure that new or changed exceptions do not conflict with existing shipments.
            'Fires against exceptions when added/changed.
            Dim br4 As New BusinessRule
            br4.MemberFunction = "ConflictingExceptionOnShipmentTest"
            br4.Source = GetType(dbiWSF.FrameworkObjects.objLoadingDockException)
            g_businessRules.BusinessRuleObjects.Add(br4)

            'Business Rule to ensure the loading dock warehouse ordinal does not conflict with another loading dock.
            'Fires against loading docks when added/changed.
            Dim br5 As New BusinessRule
            br5.MemberFunction = "ConflictingWarehouseOrdinalTest"
            br5.Source = GetType(dbiWSF.FrameworkObjects.objLoadingDock)
            g_businessRules.BusinessRuleObjects.Add(br5)

            'Business Rule to ensure that new or changed recurring exceptions do not conflict with existing shipments.
            'Fires against recurrences when added/changed.
            Dim br6 As New BusinessRule
            br6.MemberFunction = "ConflictingRecurringExceptionOnShipmentTest"
            br6.Source = GetType(dbiWSF.FrameworkObjects.objRecurrence)
            g_businessRules.BusinessRuleObjects.Add(br6)

        End Sub


#Region "**Enums**"

        ''' <summary>Enum for the types of actions requesting validation through the business rules</summary>
        Public Enum RequestAction
            ''' <summary>Addition of a WSF Object to a collection</summary>
            Add = 1
            ''' <summary>Remove a WSF Object from a collection</summary>
            Remove = 2
            ''' <summary>Change of a WSF Object in a collection</summary>
            Change = 3
            ''' <summary>View a WSF Object in a collection</summary>
            View = 4
        End Enum

        ''' <summary>Enum for the types of business rule response severity levels</summary>
        Public Enum ResponseLevel
            ''' <summary>Business Rule reports no conflict.</summary>
            Passed = 0
            ''' <summary>Business Rule reports warning but not Fatal.</summary>
            Warning = 10
            ''' <summary>Business Rule reports Fatal conflict.  Request Denied.</summary>
            Fatal = 99
        End Enum

#End Region

#Region "**Business Rule Class Objects**"

        ''' <summary>A class to store optional parameters in a BusinessRuleRequest object</summary>
        Public Class BusinessRuleRequestParameters
            Private l_collParams As New Dictionary(Of String, Object)

            ''' <summary>
            ''' A dictionary of parameters used to pass optional params to the BusinessRulesMethods
            ''' </summary>
            ''' <value>A dictionary of string/objects to use in the methods.</value>
            Public Property collParams() As Dictionary(Of String, Object)
                Get
                    Return l_collParams
                End Get
                Set(ByVal value As Dictionary(Of String, Object))
                    l_collParams = value
                End Set
            End Property

            ''' <summary>
            ''' Gets the parameter associated with the KeyName string
            ''' </summary>
            ''' <param name="KeyName">String</param>
            ''' <returns>The object value or nothing if the parameter is not found.</returns>
            ''' <remarks></remarks>
            Public Function getParamater(ByVal KeyName As String) As Object
                Dim curObject As Object
                If collParams.ContainsKey(KeyName) Then
                    curObject = collParams(KeyName)
                Else
                    curObject = Nothing
                End If
                Return curObject
            End Function
        End Class

        ''' <summary>A class to store  Business Rule Request</summary>
        Public Class BusinessRuleRequest

            Private l_Source As Object
            Private l_Action As RequestAction
            Private l_Options As BusinessRuleRequestParameters

            ''' <summary>The WSF object to process the business rules against.</summary>
            Public Property Source() As Object
                Get
                    Return l_Source
                End Get
                Set(ByVal value As Object)
                    l_Source = value
                End Set
            End Property

            ''' <summary>The requested action to check against.</summary>
            Public Property Action() As RequestAction
                Get
                    Return l_Action
                End Get
                Set(ByVal value As RequestAction)
                    l_Action = value
                End Set
            End Property

            ''' <summary>The Business Rules Parameters to use with this business rule request.</summary>
            Public Property Options() As BusinessRuleRequestParameters
                Get
                    Return l_Options
                End Get
                Set(ByVal value As BusinessRuleRequestParameters)
                    l_Options = value
                End Set
            End Property

        End Class

        ''' <summary>A class to store a business rule response</summary>
        Public Class BusinessRuleResponse
            Private l_Result As Boolean
            Private l_Responses As New List(Of String)
            Private l_Level As ResponseLevel
            Private l_OptionalReturns As New Dictionary(Of String, Object)

            ''' <summary>The result of the business rules.</summary>
            ''' <remarks>Returns true if the rules processed without issue or false if
            ''' the rules failed.</remarks>
            Public Property Result() As Boolean
                Get
                    Return l_Result
                End Get
                Set(ByVal value As Boolean)
                    l_Result = value
                End Set
            End Property

            ''' <summary>A collection of strings of the messages raised during the method.</summary>
            Public Property Responses() As Collections.Generic.List(Of String)
                Get
                    Return l_Responses
                End Get
                Set(ByVal value As Collections.Generic.List(Of String))
                    l_Responses = value
                End Set
            End Property

            ''' <summary>A response level used to gauge the maximum severity of the violations.</summary>
            Public Property Level() As ResponseLevel
                Get
                    Return l_Level
                End Get
                Set(ByVal value As ResponseLevel)
                    l_Level = value
                End Set
            End Property

            ''' <summary>Any optional return values generated in the rule processing methods.</summary>
            Public Property OptionalReturns() As Dictionary(Of String, Object)
                Get
                    Return l_OptionalReturns
                End Get
                Set(ByVal value As Dictionary(Of String, Object))
                    l_OptionalReturns = value
                End Set
            End Property

        End Class

        ''' <summary>A class to store a Business Rule</summary>
        Public Class BusinessRule

            Private l_Source As Type
            Private l_MemberFunction As String
            Private l_Parameters As Collections.Generic.List(Of Object)

            ''' <summary>The dbiWSF type that this rule will apply to.</summary>
            Public Property Source() As Type
                Get
                    Return l_Source
                End Get
                Set(ByVal value As Type)
                    l_Source = value
                End Set
            End Property

            ''' <summary>The MemberFunction name of the validating rule method</summary>
            ''' <remarks>This value is directly reflected by a Public Shared Sub
            ''' that will handle the validation for each business rule added to the collection above.</remarks>
            Public Property MemberFunction() As String
                Get
                    Return l_MemberFunction
                End Get
                Set(ByVal value As String)
                    l_MemberFunction = value
                End Set
            End Property

            ''' <summary>A list of customizable objects that can be added to the business rules.</summary>
            Public Property Parameters() As Collections.Generic.List(Of Object)
                Get
                    Return l_Parameters
                End Get
                Set(ByVal value As Collections.Generic.List(Of Object))
                    l_Parameters = value
                End Set
            End Property

        End Class

        ''' <summary>A class to store and process the collection of business rules</summary>
        Public Class BusinessRules
            Private l_RuleObjectsCollection As New Collections.Generic.List(Of BusinessRule)

            ''' <summary>The collection of business rules to apply.</summary>
            Public Property BusinessRuleObjects() As Collections.Generic.List(Of BusinessRule)
                Get
                    Return l_RuleObjectsCollection
                End Get
                Set(ByVal value As Collections.Generic.List(Of BusinessRule))
                    l_RuleObjectsCollection = value
                End Set
            End Property

            ''' <summary>A function used to trigger all business rules related to a requesting WSF Object</summary>
            ''' <param name="prRequest"></param>
            ''' <returns>BusinessRuleObjects.BusinessRuleResponse</returns>
            Private Function TriggerRules(ByVal prRequest As dbiWSF.BusinessRulesAndSupport.BusinessRuleObjects.BusinessRuleRequest) As dbiWSF.BusinessRulesAndSupport.BusinessRuleObjects.BusinessRuleResponse

                Dim ruleInProcess As String = ""

                'Create a new Business Rules Response object
                Dim prResponse As New BusinessRuleResponse

                Try

                    'Use Linq to retrieve all the business rules connected to the object requesting validation
                    Dim linqRules = From getRule As BusinessRule In Me.BusinessRuleObjects _
                                    Where getRule.Source Is prRequest.Source.GetType _
                                    Select getRule

                    'Initialize the response to Passed.  Only business rules that generate warnings or fatal errors will change the level.
                    prResponse.Level = ResponseLevel.Passed

                    For Each bRule As BusinessRule In linqRules
                        Dim memberFuctionArgs As New Collections.Generic.List(Of Object)
                        Dim instance As Type
                        Dim binder As System.Reflection.Binder = Nothing
                        Dim target As Object = Nothing

                        ruleInProcess = bRule.MemberFunction

                        'NOTE: All member functions must accept a BusinessRuleRequest and a BusinessRuleResponse.
                        'Any additional information required by a Member Function must be stored in the Request's Options Object Property.
                        memberFuctionArgs.Add(prRequest)
                        memberFuctionArgs.Add(prResponse)

                        instance = GetType(BusinessRuleObjects)

                        'Execute the member function
                        instance.InvokeMember(bRule.MemberFunction, Reflection.BindingFlags.InvokeMethod, binder, target, memberFuctionArgs.ToArray)

                    Next

                Catch ex As Exception

                    Dim exMessage As String = "Fatal Error ProcessRules: "

                    If Len(ruleInProcess) = 0 Then

                        'No rule is in process
                        exMessage = exMessage & "No Rule in Process."

                    Else

                        exMessage = exMessage & ruleInProcess

                    End If

                    prResponse.Level = ResponseLevel.Fatal

                    prResponse.Responses.Add(exMessage & " raising error " & ex.Message)

                End Try

                Return prResponse
            End Function

            ''' <summary>An overloaded function to process all business rules related to a requesting WSF Object</summary>
            ''' <param name="requestingObject"></param>
            ''' <returns>BusinessRuleObjects.BusinessRuleResponse</returns>
            ''' <remarks></remarks>
            Public Function ProcessRules(ByVal requestingObject As dbiWSF.BusinessRulesAndSupport.BusinessRuleObjects.BusinessRuleRequest) As BusinessRuleObjects.BusinessRuleResponse
                Return TriggerRules(requestingObject)
            End Function

            ''' <summary>An overloaded function to process all business rules related to a requesting WSF Object</summary>
            ''' <param name="requestingObject"></param>
            ''' <param name="requestingAction"></param>
            ''' <returns>BusinessRuleObjects.BusinessRuleResponse</returns>
            ''' <remarks></remarks>
            Public Function ProcessRules(ByVal requestingObject As Object, ByVal requestingAction As dbiWSF.BusinessRulesAndSupport.BusinessRuleObjects.RequestAction, Optional ByVal Params As dbiWSF.BusinessRulesAndSupport.BusinessRuleObjects.BusinessRuleRequestParameters = Nothing) As BusinessRuleObjects.BusinessRuleResponse
                'Create a new Business Rules Request object
                Dim prRequest As New dbiWSF.BusinessRulesAndSupport.BusinessRuleObjects.BusinessRuleRequest
                'Set the Source of the Request to the calling wsfFrameworkObject (i.e. Warehouse, Loading Dock, Shipment, etc.)
                prRequest.Source = requestingObject

                'Set the Action being requested for evaluation
                prRequest.Action = requestingAction

                'Set the Optional Parameters, if any were passed
                If Params IsNot Nothing Then
                    prRequest.Options = Params
                Else
                    prRequest.Options = New dbiWSF.BusinessRulesAndSupport.BusinessRuleObjects.BusinessRuleRequestParameters
                End If

                Return TriggerRules(prRequest)
            End Function

        End Class

#End Region

#Region "**Business Rules Functions Code**"

        '* * * * * Developer's NOTE:  All BusinessRuleObjects methods must be coded to accept a requestObject and responseObject by Reference.
        '* * * * * * * * * * * * * *  BusinessRuleObjects methods should be designed to validate actions and not initiate actions as 
        '* * * * * * * * * * * * * *  they are tested as a group for any given source object and may therefore return a Fatal
        '* * * * * * * * * * * * * *  for any individual or group of business rules.  The developer has the option of returning values in the
        '* * * * * * * * * * * * * *  Optional Parameters of the Response Object.

        ''' <summary>A Business Rule to test the cargo types of the order details on shipment relative to the cargo types accepted at a dock.</summary>
        ''' <param name="reguestObject"></param>
        ''' <param name="responseObject"></param>
        ''' <remarks>Failure results in a Warning Response.</remarks>
        Public Shared Sub DockTypeProximityTest(ByRef reguestObject As BusinessRuleRequest, ByRef responseObject As BusinessRuleResponse)
            'NOTE: This method requires a shipment object in the request's source property
            'Dim parameterName As String = "Test"

            'If reguestObject.Options.collParams.ContainsKey(parameterName) Then

            '    'We have our optional parameter.  Write to code to process parameter.

            'End If

            Try
                If reguestObject.Action = RequestAction.Add Or reguestObject.Action = RequestAction.Change Then

                    'This business rule is only enforced for new or changed shipments.

                    Dim l_Shipment As dbiWSF.FrameworkObjects.objShipment = reguestObject.Source
                    Dim l_Loadingdock As dbiWSF.FrameworkObjects.objLoadingDock = g_wsfObjects.GetLoadingDockFromGUID(l_Shipment.LoadingDockID)
                    Dim l_Warehouse As dbiWSF.FrameworkObjects.objWarehouse = g_wsfObjects.GetWarehouseFromGUID(l_Loadingdock.WarehouseID)

                    If l_Loadingdock.CargoTypes.Count > 0 Then  'Cargo types are specified on loading docks

                        For Each orderHeader As dbiWSF.FrameworkObjects.objOrderHeader In l_Shipment.OrderHeaders

                            For Each orderDetail As dbiWSF.FrameworkObjects.objOrderDetail In orderHeader.OrderDetails

                                If Not l_Loadingdock.CargoTypes.Contains(orderDetail.CargoTypeID) Then

                                    'Raise a warning
                                    If responseObject.Level < ResponseLevel.Warning Then

                                        responseObject.Level = ResponseLevel.Warning

                                    End If

                                    'Add a warning to the responses collection
                                    responseObject.Responses.Add("Warning: Order Number " & orderHeader.OrderEntryID & " contains cargo type " & g_wsfObjects.GetCargoDescripFromID(orderDetail.CargoTypeID) & " not accepted by loading dock " & l_Loadingdock.Description)

                                End If

                            Next

                        Next

                    End If

                End If

            Catch ex As Exception

                If responseObject.Level < ResponseLevel.Warning Then

                    responseObject.Level = ResponseLevel.Warning

                End If

                responseObject.Responses.Add(responseObject.Level.ToString & ex.Message)

            End Try

        End Sub

        ''' <summary>A Business Rule to test the availability of break out docks when specified on a shipment.</summary>
        ''' <param name="requestObject"></param>
        ''' <param name="responseObject"></param>
        ''' <remarks>The break out dock(s) are returned in the optional parameters of the response object as a key pair "DocksFound", collection of loading docks.
        ''' Failure results in a Fatal Response.</remarks>
        Public Shared Sub BreakOutDockTest(ByRef requestObject As BusinessRuleRequest, ByRef responseObject As BusinessRuleResponse)
            'NOTE: This method requires a Shipment object in the request's source property

            'Use the following if processing optional parameters in the request object's Options property
            'Dim parameterName As String = "Test"
            'If reguestObject.Options.collParams.ContainsKey(parameterName) Then
            '    'We have our optional parameter.  Write code to process parameter.
            'End If

            Try

                If requestObject.Action = RequestAction.Add Or requestObject.Action = RequestAction.Change Then

                    'This business rule is only enforced for new or changed shipments.

                    Dim l_Shipment As dbiWSF.FrameworkObjects.objShipment = requestObject.Source
                    Dim l_Loadingdock As dbiWSF.FrameworkObjects.objLoadingDock = g_wsfObjects.GetLoadingDockFromGUID(l_Shipment.LoadingDockID)
                    Dim l_Warehouse As dbiWSF.FrameworkObjects.objWarehouse = g_wsfObjects.GetWarehouseFromGUID(l_Loadingdock.WarehouseID)
                    Dim l_LoadingDocksFound As New Collections.Generic.List(Of dbiWSF.FrameworkObjects.objLoadingDock)

                    'Test the number of break out docks required by the shipment
                    If l_Shipment.BreakoutDockQty > 0 Then
                        'Breakout Docks are required. 

                        Dim docksFound As New Collections.Generic.List(Of dbiWSF.FrameworkObjects.objLoadingDock)

                        'Use Linq to retrieve all the loading docks within quantity of breakout docks ordinal value of the scheduled dock
                        'NOTE: The scheduled dock could be at the start (ordinal = 1) or end (ordinal = Warhouse.LoadingDocks.Count) of the warehouse.
                        Dim docks2Check = From getDock As dbiWSF.FrameworkObjects.objLoadingDock In l_Warehouse.LoadingDocks _
                                          Where getDock.WarehouseOrdinal <= l_Loadingdock.WarehouseOrdinal + l_Shipment.BreakoutDockQty _
                                          And getDock.WarehouseOrdinal >= l_Loadingdock.WarehouseOrdinal - l_Shipment.BreakoutDockQty _
                                          And getDock.WarehouseOrdinal <> l_Loadingdock.WarehouseOrdinal _
                                          Select getDock

                        For Each dock2Check As dbiWSF.FrameworkObjects.objLoadingDock In docks2Check

                            'Check to see if there are any shipments in the dock that conflict with the shipment requiring break out docks.
                            'NOTE: By definition Exceptions on a dock would allow breakouts to be handled on the dock.
                            Dim shipmentConflictsFound As New SupportObjects.shipmentConflicts
                            shipmentConflictsFound = SupportObjects.testShipmentConflict(l_Shipment, dock2Check)

                            If shipmentConflictsFound.shipmentConflicts.Count = 0 Then
                                'There are no shipments in the potential breakout dock conflicting with the shipment being scheduled.

                                docksFound.Add(dock2Check)

                            End If

                        Next    'Dock2Check

                        If docksFound.Count > 0 Then

                            'NOTE: This business rule only supports up to two break out docks

                            If l_Shipment.BreakoutDockQty = 2 And docksFound.Count > 1 Then

                                'The collection must contain 2 docks with contiguous ordinal values to include the ordinal value of the dock being tested.
                                'The possible patterns are dockOrdinal - 1, dockOrdinal - 2
                                '                          dockOrdinal - 1, dockOrdinal + 1
                                '                          dockOrdinal + 1, dockOrdinal + 2

                                Dim dock1Under As dbiWSF.FrameworkObjects.objLoadingDock = Nothing
                                Dim dock2Under As dbiWSF.FrameworkObjects.objLoadingDock = Nothing
                                Dim dock1Over As dbiWSF.FrameworkObjects.objLoadingDock = Nothing
                                Dim dock2Over As dbiWSF.FrameworkObjects.objLoadingDock = Nothing

                                For Each loadingDockFound As dbiWSF.FrameworkObjects.objLoadingDock In docksFound

                                    Select Case loadingDockFound.WarehouseOrdinal

                                        Case l_Loadingdock.WarehouseOrdinal - 2
                                            dock2Under = loadingDockFound

                                        Case l_Loadingdock.WarehouseOrdinal - 1
                                            dock1Under = loadingDockFound

                                        Case l_Loadingdock.WarehouseOrdinal + 1
                                            dock1Over = loadingDockFound

                                        Case l_Loadingdock.WarehouseOrdinal + 2
                                            dock2Over = loadingDockFound

                                    End Select

                                Next

                                'Take a look at the possible patterns
                                Select Case True

                                    Case (Not dock1Under Is Nothing) And (Not dock1Over Is Nothing)
                                        l_LoadingDocksFound.Add(dock1Under)
                                        l_LoadingDocksFound.Add(dock1Over)

                                    Case (Not dock1Under Is Nothing) And (Not dock2Under Is Nothing)
                                        l_LoadingDocksFound.Add(dock1Under)
                                        l_LoadingDocksFound.Add(dock2Under)

                                    Case (Not dock1Over Is Nothing) And (Not dock2Over Is Nothing)
                                        l_LoadingDocksFound.Add(dock1Over)
                                        l_LoadingDocksFound.Add(dock2Over)

                                    Case Else
                                        'Failure
                                        responseObject.Responses.Add("Break Out Docks Rule:  Unable to find suitable break out docks!")
                                        responseObject.Level = ResponseLevel.Fatal

                                End Select

                                If l_LoadingDocksFound.Count > 0 Then

                                    'A pair of break out docks was found.
                                    responseObject.OptionalReturns.Add("DocksFound", l_LoadingDocksFound)

                                End If

                            Else  'Only one dock was required or shipment requires 2 docks and only one or less was found.

                                If l_Shipment.BreakoutDockQty = 1 Then

                                    'if The break out dock quantity is 1 then success
                                    'Add the docks found to the response object optional parameters
                                    responseObject.OptionalReturns.Add("DocksFound", docksFound)

                                Else

                                    'Failure
                                    responseObject.Responses.Add("Break Out Docks Rule:  Unable to find suitable break out docks!")
                                    responseObject.Level = ResponseLevel.Fatal

                                End If

                            End If  'l_Shipment.BreakoutDockQty = 2 And docksFound.Count > 1

                        Else 'No docks were found and the shipment requires at least one dock.

                            'Failure
                            responseObject.Responses.Add("Break Out Docks Rule:  Unable to find suitable break out docks!")
                            responseObject.Level = ResponseLevel.Fatal

                        End If  'docksFound.Count > 0

                    End If  'The shipment requires breakout docks

                End If  'Request Action is Add or Change

            Catch ex As Exception

                If responseObject.Level < ResponseLevel.Warning Then

                    responseObject.Level = ResponseLevel.Warning

                End If

                responseObject.Responses.Add(responseObject.Level.ToString & "Break Out Docks Rule: " & ex.Message)

            End Try


        End Sub

        ''' <summary>A Business Rule to test for any conflicts with a given shipment</summary>
        ''' <param name="requestObject"></param>
        ''' <param name="responseObject"></param>
        ''' <remarks>The conflicting shipments are returned in the optional parameters of the response object as a key pair "Conflicting Shipments", 
        ''' collection of shipments.</remarks>
        Public Shared Sub ConflictingShipmentsTest(ByRef requestObject As BusinessRuleRequest, ByRef responseObject As BusinessRuleResponse)
            'NOTE: This method requires a Shipment object in the request's source property

            Try
                If requestObject.Action = RequestAction.Add Or requestObject.Action = RequestAction.Change Then

                    'This business rule is only enforced for new or changed shipments.

                    Dim l_shipment As dbiWSF.FrameworkObjects.objShipment = requestObject.Source
                    Dim l_loadingdock As dbiWSF.FrameworkObjects.objLoadingDock = g_wsfObjects.GetLoadingDockFromGUID(l_shipment.LoadingDockID)

                    Dim ConflictingShipments As New SupportObjects.shipmentConflicts

                    'Retrieve any possible conflicts between shipments
                    ConflictingShipments = SupportObjects.testShipmentConflict(l_shipment, l_loadingdock)

                    'Check for shipments that conflict with other shipments.
                    If ConflictingShipments.shipmentConflicts.Count > 0 Then
                        'If there are any conflicting shipments, add a new response to the ResponseObject
                        responseObject.Responses.Add("Shipment Conflicts with another shipment(s)")
                        'Add the conflicting Shipment(s) collection as an optional return value
                        responseObject.OptionalReturns.Add("Shipment Conflicts", ConflictingShipments)
                        'Set the level of the Response Object to Warning
                        responseObject.Level = ResponseLevel.Warning
                    End If

                    'Check for shipments that conflict with existing exceptions.
                    If ConflictingShipments.exceptionConflicts.Count > 0 Then
                        'If there are any conflicting shipments, add a new response to the ResponseObject
                        responseObject.Responses.Add("Shipment Conflicts with Exception(s)")
                        'Add the conflicting Shipment(s) collection as an optional return value
                        responseObject.OptionalReturns.Add("Shipment Conflicts", ConflictingShipments)
                        'Set the level of the Response Object to Warning
                        responseObject.Level = ResponseLevel.Warning
                    End If

                    'Check for shipments that conflict with recurring exceptions.
                    If ConflictingShipments.recurringExceptionConflicts.Count > 0 Then
                        'If there are any conflicting shipments, add a new response to the ResponseObject
                        responseObject.Responses.Add("Shipment Conflicts with Recurring Exception(s)")
                        'Add the conflicting Shipment(s) collection as an optional return value
                        responseObject.OptionalReturns.Add("Shipment Conflicts", ConflictingShipments)
                        'Set the level of the Response Object to Warning
                        responseObject.Level = ResponseLevel.Warning
                    End If
                End If
            Catch ex As Exception
                '<Generic Error> Replace as needed
                'There was an unforeseen error...
                If responseObject.Level < ResponseLevel.Warning Then
                    responseObject.Level = ResponseLevel.Warning
                End If
                responseObject.Responses.Add(responseObject.Level.ToString & "Shipment Conflict Rule: " & ex.Message)
            End Try
        End Sub

        ''' <summary>A Business Rule to test for any conflicting shipments with a given LoadingDockException</summary>
        ''' <param name="requestObject"></param>
        ''' <param name="responseObject"></param>
        ''' <remarks>The conflicting shipments are returned in the optional parameters of the response object as a key pair "Conflicting Shipments", 
        ''' collection of shipments.</remarks>
        Public Shared Sub ConflictingExceptionOnShipmentTest(ByRef requestObject As BusinessRuleRequest, ByRef responseObject As BusinessRuleResponse)
            'NOTE: This method requires a LoadingDockEception object in the request's source property

            Try
                If requestObject.Action = RequestAction.Add Or requestObject.Action = RequestAction.Change Then

                    'This business rule is only enforced for new or changed LoadingDockExceptions.

                    Dim l_LoadingDockException As dbiWSF.FrameworkObjects.objLoadingDockException = requestObject.Source

                    Dim ConflictingShipments As New SupportObjects.LoadingDockExceptionConflicts

                    'Retrieve any possible conflicts between shipments and the LoadingDockException
                    Dim curLoadingDock As dbiWSF.FrameworkObjects.objLoadingDock = requestObject.Options.getParamater("AddedDock")
                    Dim curLoadingDocks As New System.Collections.Generic.List(Of dbiWSF.FrameworkObjects.objLoadingDock)

                    If curLoadingDock IsNot Nothing Then
                        curLoadingDocks.Add(curLoadingDock)
                    Else
                        For Each LoadingDockID As System.Guid In l_LoadingDockException.LoadingDocks
                            curLoadingDocks.Add(g_wsfObjects.GetLoadingDockFromGUID(LoadingDockID))
                        Next

                    End If
                    ConflictingShipments = SupportObjects.testLoadingDockExceptionConflict(l_LoadingDockException, curLoadingDocks)


                    If ConflictingShipments.LoadingDockExceptionConflicts.Count > 0 Then
                        'If there are any conflicting shipments, add a new response to the ResponseObject
                        responseObject.Responses.Add("New exception conflicts with existing shipments...")
                        'Add the conflicting Shipment(s) collection as an optional return value
                        responseObject.OptionalReturns.Add("Conflicting Shipments ON Exception", ConflictingShipments)
                        'Set the level of the Response Object to Warning
                        responseObject.Level = ResponseLevel.Warning
                    End If

                End If
            Catch ex As Exception
                '<Generic Error> Replace as needed
                If responseObject.Level < ResponseLevel.Warning Then
                    responseObject.Level = ResponseLevel.Warning
                End If

                responseObject.Responses.Add(responseObject.Level.ToString & "Exception Conflict Rule: " & ex.Message)
            End Try
        End Sub

        ''' <summary>A Business Rule to test for any conflicting WarehouseOrdinal values in a warehouse from a given LoadingDock</summary>
        ''' <param name="requestObject"></param>
        ''' <param name="responseObject"></param>
        ''' <remarks>The conflicting loading dock is returned in the optional parameters of the response object as a key pair "Conflicting Warehouse Ordinal", 
        ''' LoadingDock.</remarks>
        Public Shared Sub ConflictingWarehouseOrdinalTest(ByRef requestObject As BusinessRuleRequest, ByRef responseObject As BusinessRuleResponse)
            'NOTE: This method requires a LoadingDock object in the request's source property

            Try
                If requestObject.Action = RequestAction.Add Or requestObject.Action = RequestAction.Change Then

                    'This business rule is only enforced for new or changed LoadingDocks.

                    Dim l_LoadingDock As dbiWSF.FrameworkObjects.objLoadingDock = requestObject.Source
                    Dim l_Warehouse As dbiWSF.FrameworkObjects.objWarehouse = g_wsfObjects.GetWarehouseFromGUID(l_LoadingDock.WarehouseID)

                    For Each LoadingDock As dbiWSF.FrameworkObjects.objLoadingDock In l_Warehouse.LoadingDocks
                        If l_LoadingDock.WarehouseOrdinal = LoadingDock.WarehouseOrdinal Then
                            If l_LoadingDock.LoadingDockID <> LoadingDock.LoadingDockID Then
                                'If there are any conflicting loading docks, add a new response to the ResponseObject
                                responseObject.Responses.Add("Warehouse Ordinal Conflict")
                                'Add the conflicting loading dock as an optional return value
                                responseObject.OptionalReturns.Add("Conflicting Warehouse Ordinal", LoadingDock)
                                'Set the level of the Response Object to Warning
                                responseObject.Level = ResponseLevel.Warning
                                Exit For
                            End If
                        End If
                    Next
                End If
            Catch ex As Exception
                If responseObject.Level < ResponseLevel.Warning Then

                    responseObject.Level = ResponseLevel.Warning

                End If

                responseObject.Responses.Add(responseObject.Level.ToString & "Warehouse Ordinal Conflict Rule: " & ex.Message)
            End Try
        End Sub

        ''' <summary>A Business Rule to test for any conflicting shipments with a given Recurring LoadingDockException</summary>
        ''' <param name="requestObject"></param>
        ''' <param name="responseObject"></param>
        ''' <remarks>The conflicting shipments are returned in the optional parameters of the response object as a key pair "Conflicting Shipments", 
        ''' collection of shipments.</remarks>
        Public Shared Sub ConflictingRecurringExceptionOnShipmentTest(ByRef requestObject As BusinessRuleRequest, ByRef responseObject As BusinessRuleResponse)
            'NOTE: This method requires a LoadingDockEception object in the request's source property

            Try
                If requestObject.Action = RequestAction.Add Or requestObject.Action = RequestAction.Change Then

                    'This business rule is only enforced for new or changed Recurring LoadingDockExceptions.

                    Dim l_RecurringLoadingDockException As dbiWSF.FrameworkObjects.objRecurrence = requestObject.Source

                    If l_RecurringLoadingDockException.ObjectType = FrameworkObjects.RecurrenceObjectType.DockException Then
                        Dim ConflictingShipments As New SupportObjects.LoadingDockExceptionConflicts

                        'Retrieve any possible conflicts between shipments and the LoadingDockException
                        Dim curLoadingDock As dbiWSF.FrameworkObjects.objLoadingDock = requestObject.Options.getParamater("AddedDock")
                        Dim curLoadingDocks As New System.Collections.Generic.List(Of dbiWSF.FrameworkObjects.objLoadingDock)

                        If curLoadingDock IsNot Nothing Then
                            curLoadingDocks.Add(curLoadingDock)
                        Else
                            For Each LoadingDockID As System.Guid In l_RecurringLoadingDockException.RecurringObjects
                                curLoadingDocks.Add(g_wsfObjects.GetLoadingDockFromGUID(LoadingDockID))
                            Next

                        End If
                        ConflictingShipments = SupportObjects.testRecurringLoadingDockExceptionConflict(l_RecurringLoadingDockException, curLoadingDocks)


                        If ConflictingShipments.LoadingDockExceptionConflicts.Count > 0 Then
                            'If there are any conflicting shipments, add a new response to the ResponseObject
                            responseObject.Responses.Add("Recurring object conflicts with existing shipment...")
                            'Add the conflicting Shipment(s) collection as an optional return value
                            responseObject.OptionalReturns.Add("Conflicting Shipments ON Exception", ConflictingShipments)
                            'Set the level of the Response Object to Warning
                            responseObject.Level = ResponseLevel.Warning
                        End If
                    End If
                End If
            Catch ex As Exception
                '<Generic Error> Replace as needed
                If responseObject.Level < ResponseLevel.Warning Then
                    responseObject.Level = ResponseLevel.Warning
                End If
                responseObject.Responses.Add(responseObject.Level.ToString & "Exception Conflict Rule: " & ex.Message)
            End Try
        End Sub
#End Region

#Region "!!Business Rule Function Template!!"
        'This is a template for a business rule method
        '''' <summary>A Business Rule to ... </summary>
        '''' <param name="reguestObject"></param>
        '''' <param name="responseObject"></param>
        '''' <remarks>Place optional parameters in the BusinessRuleRequest.Options property</remarks>
        'Public Shared Sub DockTypeProximityTest(ByRef reguestObject As BusinessRuleRequest, ByRef responseObject As BusinessRuleResponse)
        '    'NOTE: This method requires a ???? object in the request's source property

        '    'Use the following if processing optional parameters in the request object's Options property
        '    'Dim parameterName As String = "Test"
        '    'If reguestObject.Options.collParams.ContainsKey(parameterName) Then
        '    '    'We have our optional parameter.  Write to code to process parameter.
        '    'End If

        '    Try
        '        'Place Business Rule Code here ...

        '    Catch ex As Exception

        '        If responseObject.Level < ResponseLevel.Warning Then

        '            responseObject.Level = ResponseLevel.Warning

        '        End If

        '        responseObject.Responses.Add(responseObject.Level.ToString & ex.Message)

        '    End Try

        'End Sub
#End Region

    End Class

    Public Class SupportObjects
        'The dbiWSFSupportOjbects class holds methods that support the operation of the Business Rules Objects and the UI objects.

        ''' <summary>An object to store conflicts within a schedule for a given shipment </summary>
        ''' <remarks></remarks>
        Public Class shipmentConflicts
            Private l_shipmentConflicts As New Collections.Generic.List(Of dbiWSF.FrameworkObjects.objShipment)
            Private l_exceptionConflicts As New Collections.Generic.List(Of dbiWSF.FrameworkObjects.objLoadingDockException)
            Private l_recurringExceptionConflicts As New Collections.Generic.List(Of dbiWSF.FrameworkObjects.objRecurrence)
            Private l_errorEncountered As Exception

            ''' <summary>Shipment Conflicts</summary>
            Public Property shipmentConflicts() As Collections.Generic.List(Of dbiWSF.FrameworkObjects.objShipment)
                Get
                    Return l_shipmentConflicts
                End Get
                Set(ByVal value As Collections.Generic.List(Of dbiWSF.FrameworkObjects.objShipment))
                    l_shipmentConflicts = value
                End Set
            End Property

            ''' <summary>Exception Conflicts</summary>
            Public Property exceptionConflicts() As Collections.Generic.List(Of dbiWSF.FrameworkObjects.objLoadingDockException)
                Get
                    Return l_exceptionConflicts
                End Get
                Set(ByVal value As Collections.Generic.List(Of dbiWSF.FrameworkObjects.objLoadingDockException))
                    l_exceptionConflicts = value
                End Set
            End Property

            ''' <summary>Recurring Conflicts</summary>
            Public Property recurringExceptionConflicts() As Collections.Generic.List(Of dbiWSF.FrameworkObjects.objRecurrence)
                Get
                    Return l_recurringExceptionConflicts
                End Get
                Set(ByVal value As Collections.Generic.List(Of dbiWSF.FrameworkObjects.objRecurrence))
                    l_recurringExceptionConflicts = value
                End Set
            End Property

            ''' <summary>Any exceptions that were generated by the calling methods.</summary>
            Public Property errorEncountered() As SystemException
                Get
                    Return l_errorEncountered
                End Get
                Set(ByVal value As SystemException)
                    l_errorEncountered = value
                End Set
            End Property

        End Class

        ''' <summary>A method to return all shipments and/or loading dock exceptions in conflict with a given shipment</summary>
        ''' <param name="shipment2Test"></param>
        ''' <param name="loadingDock2Test"></param>
        ''' <returns>shipmentConflicts</returns>
        ''' <remarks></remarks>
        Public Shared Function testShipmentConflict(ByVal shipment2Test As dbiWSF.FrameworkObjects.objShipment, Optional ByVal loadingDock2Test As dbiWSF.FrameworkObjects.objLoadingDock = Nothing) As shipmentConflicts

            Dim conflicts4Shipment As New shipmentConflicts 'An object to carry the objects (shipments and exceptions) in conflict with the shipment

            Try

                If loadingDock2Test Is Nothing Then     'The optional loading dock parameter was not specified.

                    'Use the dock attached to the shipment2Test object parameter.
                    loadingDock2Test = BusinessRuleObjects.g_wsfObjects.GetLoadingDockFromGUID(shipment2Test.LoadingDockID)

                End If

                'Look through the loading dock for conflicts with the given shipment.
                For Each shipmentInDock As dbiWSF.FrameworkObjects.objShipment In loadingDock2Test.Shipments

                    If timeOverlap(shipment2Test.SchedStartTime, shipment2Test.SchedEndTime, shipmentInDock.SchedStartTime, shipmentInDock.SchedEndTime, 15) Then
                        'Add the shipment in conflict to the shipmentConflicts object
                        If shipment2Test.ShipmentID <> shipmentInDock.ShipmentID Then
                            conflicts4Shipment.shipmentConflicts.Add(shipmentInDock)
                        End If

                    End If

                Next

                'Look through the loading dock for conflicts with the given shipment

                'Get the exceptions for the loading dock
                Dim linqGetExceptions = From curException As dbiWSF.FrameworkObjects.objLoadingDockException In BusinessRuleObjects.g_wsfObjects.LoadingDockExceptions _
                                        Where curException.LoadingDocks.Contains(loadingDock2Test.LoadingDockID) _
                                        Select curException

                For Each loadingDockException As dbiWSF.FrameworkObjects.objLoadingDockException In linqGetExceptions

                    If timeOverlap(shipment2Test.SchedStartTime, shipment2Test.SchedEndTime, loadingDockException.StartDate, loadingDockException.EndDate, 15) Then
                        'Add the exception in conflict with the given shipment.
                        conflicts4Shipment.exceptionConflicts.Add(loadingDockException)

                    End If

                Next

                'Get the recurring exceptions for the loading dock
                Dim linqGetRecurringException = From curRecurrence As dbiWSF.FrameworkObjects.objRecurrence In BusinessRuleObjects.g_wsfObjects.Recurrences _
                                                Where curRecurrence.RecurringObjects.Contains(loadingDock2Test.LoadingDockID) _
                                                Select curRecurrence

                For Each Recurrence As dbiWSF.FrameworkObjects.objRecurrence In linqGetRecurringException
                    Select Case Recurrence.RecurrenceType
                        Case dbiWSF.FrameworkObjects.RecurrenceTypes.Daily
                            Dim spanDays As Long = DateDiff(DateInterval.Day, Recurrence.RecurringStartDate, Recurrence.RecurringEndDate)

                            For curDay As Long = 0 To spanDays Step Recurrence.Frequency
                                Dim nowDate As Date = Recurrence.RecurringStartDate.AddDays(curDay)
                                If timeOverlap(shipment2Test.SchedStartTime, shipment2Test.SchedEndTime, nowDate.Date.AddHours(Recurrence.ObjectStartDate.Hour), nowDate.Date.AddHours(Recurrence.ObjectEndDate.Hour), 15) Then
                                    conflicts4Shipment.recurringExceptionConflicts.Add(Recurrence)
                                End If
                            Next
                        Case dbiWSF.FrameworkObjects.RecurrenceTypes.Monthly
                            Dim spanMonth As Long = DateDiff(DateInterval.Month, Recurrence.RecurringStartDate, Recurrence.RecurringEndDate)

                            For curMonth As Long = 0 To spanMonth Step Recurrence.Frequency
                                Dim nowDate As Date = Recurrence.RecurringStartDate.AddMonths(curMonth)
                                If timeOverlap(shipment2Test.SchedStartTime, shipment2Test.SchedEndTime, nowDate.Date.AddHours(Recurrence.ObjectStartDate.Hour), nowDate.Date.AddHours(Recurrence.ObjectEndDate.Hour), 15) Then
                                    conflicts4Shipment.recurringExceptionConflicts.Add(Recurrence)
                                End If
                            Next
                        Case dbiWSF.FrameworkObjects.RecurrenceTypes.Weekly
                            Dim myDates As New System.Collections.Generic.List(Of Date)
                            myDates = BusinessRuleObjects.g_wsfObjects.FixedDates(Recurrence.RecurringStartDate, Recurrence.RecurringEndDate, Recurrence.Frequency, Recurrence.DaysOfWeek)
                            For Each curDate As Date In myDates
                                If timeOverlap(shipment2Test.SchedStartTime, shipment2Test.SchedEndTime, curDate.Date.AddHours(Recurrence.ObjectStartDate.Hour), curDate.Date.AddHours(Recurrence.ObjectEndDate.Hour), 15) Then
                                    conflicts4Shipment.recurringExceptionConflicts.Add(Recurrence)
                                End If
                            Next

                        Case dbiWSF.FrameworkObjects.RecurrenceTypes.Custom

                            Dim myDates As New System.Collections.Generic.List(Of Date)
                            'Pass in date collection here.
                            'myDates = DateCollection
                            For Each curDate As Date In myDates
                                If timeOverlap(shipment2Test.SchedStartTime, shipment2Test.SchedEndTime, curDate.Date.AddHours(Recurrence.ObjectStartDate.Hour), curDate.Date.AddHours(Recurrence.ObjectEndDate.Hour), 15) Then
                                    conflicts4Shipment.recurringExceptionConflicts.Add(Recurrence)
                                End If
                            Next

                    End Select

                Next



            Catch ex As Exception
                'Return the error in the shipmentConflicts object.
                conflicts4Shipment.errorEncountered = ex

            End Try

            Return conflicts4Shipment

        End Function

        ''' <summary>An object to store conflicts within a schedule for a given LoadingDockException or Recurring LoadingDockException </summary>
        ''' <remarks></remarks>
        Public Class LoadingDockExceptionConflicts
            Private l_ShipmentConflicts As New Collections.Generic.List(Of dbiWSF.FrameworkObjects.objShipment)
            Private l_errorEncountered As Exception

            ''' <summary>
            ''' A Collection of shipments that conflict with the supplied exception.
            ''' </summary>
            ''' <value></value>
            ''' <returns>Collection of DbiWSF.FrameworkObjects.ObjShipments</returns>
            ''' <remarks></remarks>
            Public Property LoadingDockExceptionConflicts() As Collections.Generic.List(Of dbiWSF.FrameworkObjects.objShipment)
                Get
                    Return l_ShipmentConflicts
                End Get
                Set(ByVal value As Collections.Generic.List(Of dbiWSF.FrameworkObjects.objShipment))
                    l_ShipmentConflicts = value
                End Set
            End Property

            ''' <summary>
            ''' A recorded error that occurred when processing the business rule.
            ''' </summary>
            ''' <value></value>
            ''' <returns>a SystemException describing the error that was encountered when firing the business rule</returns>
            ''' <remarks></remarks>
            Public Property errorEncountered() As SystemException
                Get
                    Return l_errorEncountered
                End Get
                Set(ByVal value As SystemException)
                    l_errorEncountered = value
                End Set
            End Property

        End Class

        ''' <summary>A method to return all shipments in conflict with a given LoadingDockException</summary>
        ''' <param name="LoadingDockException2Test">the Loading Dock exception to test for shipment conflicts</param>
        ''' <returns>LoadingDockExceptionConflicts</returns>
        ''' <remarks></remarks>
        Public Shared Function testLoadingDockExceptionConflict(ByVal LoadingDockException2Test As dbiWSF.FrameworkObjects.objLoadingDockException, _
                                                                ByVal curLoadingDocks As System.Collections.Generic.List(Of dbiWSF.FrameworkObjects.objLoadingDock)) _
                                                                As LoadingDockExceptionConflicts

            Dim conflicts4LoadingDockException As New LoadingDockExceptionConflicts 'An object to carry the objects (LoadingDockExceptions and exceptions) in conflict with the LoadingDockException

            Try
                'Look through the loading dock for conflicts with the given LoadingDockException.
                For Each LoadingDock As dbiWSF.FrameworkObjects.objLoadingDock In curLoadingDocks

                    For Each ShipmentInDock As dbiWSF.FrameworkObjects.objShipment In LoadingDock.Shipments

                        If timeOverlap(LoadingDockException2Test.StartDate, LoadingDockException2Test.EndDate, ShipmentInDock.SchedStartTime, ShipmentInDock.SchedEndTime, 15) Then
                            'Add the LoadingDockException in conflict to the LoadingDockExceptionConflicts object

                            conflicts4LoadingDockException.LoadingDockExceptionConflicts.Add(ShipmentInDock)
                        End If

                    Next
                Next
            Catch ex As Exception
                'Return the error in the LoadingDockExceptionConflicts object.
                conflicts4LoadingDockException.errorEncountered = ex

            End Try

            Return conflicts4LoadingDockException

        End Function

        ''' <summary>A method to return all shipments in conflict with a given Recurring LoadingDockException</summary>
        ''' <param name="RecurringLoadingDockException2Test">the recurring exception to test for shipment conflicts</param>
        ''' <returns>LoadingDockExceptionConflicts</returns>
        ''' <remarks></remarks>
        Public Shared Function testRecurringLoadingDockExceptionConflict(ByVal RecurringLoadingDockException2Test As dbiWSF.FrameworkObjects.objRecurrence, ByVal curLoadingDocks As System.Collections.Generic.List(Of dbiWSF.FrameworkObjects.objLoadingDock)) As LoadingDockExceptionConflicts

            Dim conflicts4LoadingDockException As New LoadingDockExceptionConflicts 'An object to carry the objects (Shipments) in conflict with the LoadingDockException

            Try

                'Look through the loading dock for conflicts with the given LoadingDockException.
                For Each curLoadingDock As dbiWSF.FrameworkObjects.objLoadingDock In curLoadingDocks

                    For Each ShipmentInDock As dbiWSF.FrameworkObjects.objShipment In curLoadingDock.Shipments

                        Select Case RecurringLoadingDockException2Test.RecurrenceType
                            Case dbiWSF.FrameworkObjects.RecurrenceTypes.Daily
                                Dim spanDays As Long = DateDiff(DateInterval.Day, RecurringLoadingDockException2Test.RecurringStartDate, RecurringLoadingDockException2Test.RecurringEndDate)

                                For curDay As Long = 0 To spanDays Step RecurringLoadingDockException2Test.Frequency
                                    Dim nowDate As Date = RecurringLoadingDockException2Test.RecurringStartDate.AddDays(curDay)
                                    If timeOverlap(ShipmentInDock.SchedStartTime, ShipmentInDock.SchedEndTime, nowDate.Date.AddMilliseconds(RecurringLoadingDockException2Test.ObjectStartDate.TimeOfDay.TotalMilliseconds), nowDate.Date.AddMilliseconds(RecurringLoadingDockException2Test.ObjectEndDate.TimeOfDay.TotalMilliseconds), 15) Then
                                        conflicts4LoadingDockException.LoadingDockExceptionConflicts.Add(ShipmentInDock)
                                    End If
                                Next
                            Case dbiWSF.FrameworkObjects.RecurrenceTypes.Monthly
                                Dim spanMonth As Long = DateDiff(DateInterval.Month, RecurringLoadingDockException2Test.RecurringStartDate, RecurringLoadingDockException2Test.RecurringEndDate)

                                For curMonth As Long = 0 To spanMonth Step RecurringLoadingDockException2Test.Frequency
                                    Dim nowDate As Date = RecurringLoadingDockException2Test.RecurringStartDate.AddMonths(curMonth)
                                    If timeOverlap(ShipmentInDock.SchedStartTime, ShipmentInDock.SchedEndTime, nowDate.Date.AddMilliseconds(RecurringLoadingDockException2Test.ObjectStartDate.TimeOfDay.TotalMilliseconds), nowDate.Date.AddMilliseconds(RecurringLoadingDockException2Test.ObjectEndDate.TimeOfDay.TotalMilliseconds), 15) Then
                                        conflicts4LoadingDockException.LoadingDockExceptionConflicts.Add(ShipmentInDock)
                                    End If
                                Next
                            Case dbiWSF.FrameworkObjects.RecurrenceTypes.Weekly
                                Dim myDates As New System.Collections.Generic.List(Of Date)
                                myDates = BusinessRuleObjects.g_wsfObjects.FixedDates(RecurringLoadingDockException2Test.RecurringStartDate, RecurringLoadingDockException2Test.RecurringEndDate, RecurringLoadingDockException2Test.Frequency, RecurringLoadingDockException2Test.DaysOfWeek)
                                For Each curDate As Date In myDates
                                    If timeOverlap(ShipmentInDock.SchedStartTime, ShipmentInDock.SchedEndTime, curDate.Date.AddMilliseconds(RecurringLoadingDockException2Test.ObjectStartDate.TimeOfDay.TotalMilliseconds), curDate.Date.AddMilliseconds(RecurringLoadingDockException2Test.ObjectEndDate.TimeOfDay.TotalMilliseconds), 15) Then
                                        conflicts4LoadingDockException.LoadingDockExceptionConflicts.Add(ShipmentInDock)
                                    End If
                                Next

                            Case dbiWSF.FrameworkObjects.RecurrenceTypes.Custom

                                Dim myDates As New System.Collections.Generic.List(Of Date)
                                'Pass in date collection here.
                                'myDates = DateCollection
                                For Each curDate As Date In myDates
                                    If timeOverlap(ShipmentInDock.SchedStartTime, ShipmentInDock.SchedEndTime, curDate.Date.AddMilliseconds(RecurringLoadingDockException2Test.ObjectStartDate.TimeOfDay.TotalMilliseconds), curDate.Date.AddMilliseconds(RecurringLoadingDockException2Test.ObjectEndDate.TimeOfDay.TotalMilliseconds), 15) Then
                                        conflicts4LoadingDockException.LoadingDockExceptionConflicts.Add(ShipmentInDock)
                                    End If
                                Next

                        End Select

                    Next
                Next
            Catch ex As Exception
                'Return the error in the LoadingDockExceptionConflicts object.
                conflicts4LoadingDockException.errorEncountered = ex

            End Try

            Return conflicts4LoadingDockException

        End Function

#Region "--General Reusable Functions--"
        ''' <summary>A method to determine if two objects overlap each other given their start and end DateTimes.</summary>
        ''' <param name="obj1Start">The start datetime of the first object to compare.</param>
        ''' <param name="obj1End">The end datetime of the first object to compare.</param>
        ''' <param name="obj2Start">The start datetime of the second object to compare.</param>
        ''' <param name="obj2End">The end datetime of the second object to compare.</param>
        ''' <returns>boolean</returns>
        ''' <remarks>The timeOverlap method tests the three overlap patterns to determine if an object conflicts with another.</remarks>
        Public Shared Function timeOverlap(ByVal obj1Start As DateTime, ByVal obj1End As DateTime, ByVal obj2Start As DateTime, ByVal obj2End As DateTime, ByVal ProximityTolerance As Integer) As Boolean
            Dim timeOverlapReturn As Boolean = False
            'Test each overlap pattern for an overlap in time.

            'Pattern 1
            'O1S------01E
            '    02S--------O2E

            If obj1End > obj2Start.AddMinutes(ProximityTolerance) And obj1End <= obj2End Then

                timeOverlapReturn = True

            End If

            'Pattern 2
            '          O1S------01E
            '    02S--------O2E
            ' or
            '   O1S--------01E
            '02S--------------O2E

            If obj1Start >= obj2Start And obj1Start < obj2End.AddMinutes(-ProximityTolerance) Then

                timeOverlapReturn = True

            End If

            'Pattern 3
            'O1S--------------01E
            '   02S--------O2E

            If obj1Start <= obj2Start And obj1End >= obj2End Then

                timeOverlapReturn = True

            End If

            'Return the boolean variable value
            timeOverlap = timeOverlapReturn

        End Function
#End Region

    End Class
End Namespace
